import hashlib
import hmac
import json
import requests
import time
import urllib.parse
import sys


from coin.exchange.base.kr_rest.auth_base import AuthKey
from coin2.api_client.common import (SyncQueryer)


class MercadobitcoinAuth(requests.auth.AuthBase):
  def __init__(self, key):
    self._key = AuthKey.from_file(key)
    self._token = ""

  def set_token(self, token):
    self._token = token
  
  def __call__(self, req: requests.PreparedRequest):
    query = urllib.parse.urlparse(req.url)
    
    params = urllib.parse.parse_qsl(query.query)
    params = dict(params)
    if "limitPrice" in params:
     params["limitPrice"] = float(params["limitPrice"]) 

    if query.path == "/api/v4/authorize":
      params['login'] = self._key.access_key
      params['password'] = self._key._secret_key
    else:
      req.headers.update({"Authorization": self._token})

    req.headers.update({"Content-Type": "application/json"})
    if req.method == "POST":
      url = urllib.parse.ParseResult(query.scheme,
                                  query.netloc,
                                  query.path,
                                  '',
                                  '',
                                  '').geturl()
      req.url = url
      req.body = json.dumps(params, indent=2)
    return req

class MercadobitcoinPrivateClient():
  def __init__(self, key_path: str, mea: str, ip=None, proxies = {'https':'socks5://127.0.0.1:9999'}):
    self._key = AuthKey.from_file(key_path)
    self._auth = MercadobitcoinAuth(key_path)
    self._url = "https://api.mercadobitcoin.net/"
    self._query = SyncQueryer(api_host=self._url, auth=self._auth, ip=ip, proxies=proxies)
    self._token = self.token()["access_token"]
    self._auth.set_token(self._token)
    self._account = self.accounts("BRL")

  def token(self):
    path = "api/v4/authorize"
    method = "POST"
    response = self._query.query(method=method, path=path)
    resp = response.json()
    return resp
  
  def accounts(self, currency):
    path = "api/v4/accounts"
    method = "GET"
    response = self._query.query(method=method, path=path)
    resp = response.json()
    for item in resp:
      if item["currency"] == currency:
        return item["id"]
    
    return ""

  def balances(self):
    path = "api/v4/accounts/{}/balances".format(self._account)
    method = "GET"
    response = self._query.query(method=method, path=path)
    response = response.json()
    
    resp_list = []  
    for item in response:
      if float(item["total"]) > 0:
        resp_list.append(item)
        
    return resp_list

  def open_order(self, symbol):
    path = "api/v4/accounts/{}/{}/orders".format(self._account, symbol)
    method = "GET"
    params = {"status": "working"}
    response = self._query.query(method=method, path=path, params=params)
    return response

  def cancel_order(self, symbol, id):
    path = "api/v4/accounts/{}/{}/orders/{}".format(self._account, symbol, id)
    method = "DELETE"
    response = self._query.query(method=method, path=path)
    return response

  def cancel_all(self, symbol):
    path = "api/v4/accounts/{}/cancel_all_open_orders".format(self._account)
    method = "DELETE"
    params = {"symbol": symbol}
    response = self._query.query(method=method, path=path, params=params)
    return response

  def order_detail(self, symbol, order_id):
    path = "api/v4/accounts/{}/{}/orders/{}".format(self._account, symbol, order_id)
    method = "GET"
    response = self._query.query(method=method, path=path)
    return response
  
  def place_order(self, price, qty, side, type, symbol, id = ""):
    path = "api/v4/accounts/{}/{}/orders".format(self._account, symbol)
    method = "POST"
    params = {"limitPrice": float(price), "qty": qty, "side": side, "type": type}
    if type == "stoplimit":
      params["externalId"] = id

    response = self._query.query(method=method, path=path, params=params)
    
    return response    

if __name__ == "__main__":
  key_path = sys.argv[1]
  config = {}
  config["key_path"] = key_path

  mercadobitcoin = MercadobitcoinPrivateClient(key_path, "Spot.Mercado.v4")
  resp = mercadobitcoin.open_order("ETH-BRL")
  resp = resp.json()
  print(resp)

  # resp = mercadobitcoin.cancel_order("ETH-BRL", "404266314")
  # print(resp.text)
  
  # resp = mercadobitcoin.cancel_all("ETH-BRL")
  # print(resp.text)

  # balances = mercadobitcoin.balances()
  # print(balances)
  
  # resp = mercadobitcoin.order_detail("ETH-BRL", "404266314")
  # print(resp.text)
  
  # resp = mercadobitcoin.place_order("7000", 0.001, "buy", "limit", "ETH-BRL")
  # print(resp.json())